/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.RawMaterialPurchase;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import merlion.common.util.Consts;
import merlion.mrp.ppm.session.MRPSessionLocal;
import merlion.scm.rmpm.entity.PurchasePlan;
import merlion.scm.rmpm.entity.RawMaterial;
import merlion.scm.rmpm.entity.RawMaterialPurchaseOrder;
import merlion.scm.rmpm.entity.RawMaterialSupplyInformation;
import merlion.scm.rmpm.entity.Supplier;
import merlion.scm.rmpm.pojo.SupplierListRow;
import merlion.scm.rmpm.session.RawMaterialPurchaseSessionBeanLocal;
import org.primefaces.context.RequestContext;

/**
 *
 * @author Kenn
 */
@ManagedBean(name = "prManagerBean")
@ViewScoped
public class PurchaseRequirementsManagerBean {

    @EJB
    private RawMaterialPurchaseSessionBeanLocal rmpSessionBean;
    @EJB
    private MRPSessionLocal mrpSessionBean;
    private Date date;
    private ArrayList<SupplierListRow> suppliersList;
    private ArrayList<SupplierListRow> suppliersListBackup;
    private ArrayList<Long> requirements;
    private int index;
    private SupplierListRow sr;
    private RawMaterialSupplyInformation rmsi;
    private Long quantity;
    private PurchasePlan purchasePlan;
    private Boolean currency;
    private Boolean urgent;
    private RawMaterialPurchaseOrder rmpo;
    private String statusMsg;

    //--------------------------------------------------------------------------
    //                               Constructor
    //--------------------------------------------------------------------------
    public PurchaseRequirementsManagerBean() {
    }

    @PostConstruct
    public void init() {

        rmpo = (RawMaterialPurchaseOrder) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("rmpo");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("rmpo");
        purchasePlan = (PurchasePlan) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("purchasePlan");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("purchasePlan");
        currency = (Boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("currency");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("currency");
        urgent = (Boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("urgent");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("urgent");
        suppliersList = (ArrayList<SupplierListRow>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("suppliersList");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("suppliersList");
        requirements = (ArrayList<Long>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("requirements");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("requirements");
        date = (Date) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("date");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("date");
        statusMsg = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("statusMsg");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("statusMsg");

    }

    //--------------------------------------------------------------------------
    //                             Manager Bean Method
    //--------------------------------------------------------------------------
    public void generateSupplierListRow(ActionEvent event) {

        //Validate date
        boolean valid = true;
        RequestContext context = RequestContext.getCurrentInstance();
        if (date == null) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Date is required", ""));
            valid = false;
        }
        if (date != null) {
            if (date.getDay() != 1) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Date chosen must be a Monday", ""));
                valid = false;
            }
        }
        if (currency == null) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Currency is required", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);

        // TO DO: Link with MRP here
        System.out.println("Year: " + date.getYear() + " Month: " + date.getMonth() + " Day: " + date.getDate());
        requirements = mrpSessionBean.getMRPPurchasePlan(date);
        System.out.println("ArrayList size: " + requirements.size());

        ArrayList<Supplier> suppliers = new ArrayList<Supplier>(rmpSessionBean.getAllSupplier());

        ArrayList<RawMaterial> rmObjects = new ArrayList<RawMaterial>();
        for (String s : Consts.allRawMaterialNames) {
            rmObjects.add(rmpSessionBean.getRawMaterialbyName(s));
        }

        ArrayList<SupplierListRow> supplierListRows = new ArrayList<SupplierListRow>();

        for (Supplier s : suppliers) {
            SupplierListRow slr = new SupplierListRow(s, rmObjects);
            supplierListRows.add(slr);
        }

        suppliersList = new ArrayList<SupplierListRow>(supplierListRows);
    }

    public void editQuantity(ActionEvent event) {
        index = ((Long) event.getComponent().getAttributes().get("index")).intValue();
        sr = (SupplierListRow) event.getComponent().getAttributes().get("supplierRow");
        quantity = sr.getPurchases().get(index);

        for (RawMaterialSupplyInformation info : sr.getSupplier().getRawMaterialsSupplied()) {
            if (info.getRawMaterial().equals(sr.getMaterials().get(index))) {
                rmsi = info;
            }
        }

        System.out.println("Index Value: " + index);
        System.out.println("Supplier List Row Supplier: " + sr.getSupplier().getSupplierName());
        System.out.println("Raw Material: " + rmsi.getRawMaterial().getName());
    }

    public void updateEditQuantity(ActionEvent event) {
        sr.getPurchases().set(index, quantity);
    }

    public void cancelEditQuantity(ActionEvent event) {
    }

    public void displayPurchaseOrder(ActionEvent event) {
        rmpo = (RawMaterialPurchaseOrder) event.getComponent().getAttributes().get("selected");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("rmpo", rmpo);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("purchasePlan", purchasePlan);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("currency", currency);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("urgent", urgent);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("date", date);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("suppliersList", suppliersList);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("requirements", requirements);
    }

    public void back(ActionEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("purchasePlan", purchasePlan);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("currency", currency);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("urgent", urgent);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("date", date);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("suppliersList", suppliersList);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("requirements", requirements);
    }

    public void generatePurchasePlan(ActionEvent event) {

        ArrayList<RawMaterial> rmObjects = new ArrayList<RawMaterial>();
        for (String s : Consts.allRawMaterialNames) {
            rmObjects.add(rmpSessionBean.getRawMaterialbyName(s));
        }

        RequestContext context = RequestContext.getCurrentInstance();

        boolean valid = true;
        for (int i = 0; i < 23; i++) {

            long materialTotal = 0l;
            for (SupplierListRow sr : suppliersList) {
                materialTotal += sr.getPurchases().get(i);
            }
            if (materialTotal < (long) requirements.get(i).longValue()) {
                valid = false;
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Material ordered for " + rmObjects.get(i).getName() + " is insufficient for requirements", ""));
            }

        }
        context.addCallbackParam("valid", valid);

        if (!valid) {
            return;
        }

        purchasePlan = rmpSessionBean.createPurchasePlan(suppliersList, currency, urgent);
        purchasePlan.setDatePurchasePlan(new Timestamp(date.getTime()));
    }

    public void updatePurchasePlan(ActionEvent event) {
        suppliersListBackup = new ArrayList<SupplierListRow>();
        for (SupplierListRow slr : suppliersList) {
            SupplierListRow s = slr.clone();
            suppliersListBackup.add(s);
        }
    }

    public void cancelUpdatePurchasePlan(ActionEvent event) {
        suppliersList = suppliersListBackup;
    }

    public Collection<RawMaterial> getAllRawMaterial() {
        return rmpSessionBean.getAllRawMaterial();
    }

    public String savePurchasePlan() {

        purchasePlan = rmpSessionBean.savePurchasePlan(purchasePlan);

        if (purchasePlan != null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Purchase Plan and Purchase Orders saved successfully.");
        } else {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Purchase Plan and Purchase Orders failed to save. Please try again.");
        }
        return "viewPurchasePlanStatus?faces-redirect=true";
    }

    public Collection<PurchasePlan> getAllPurchasePlan() {
        return rmpSessionBean.getAllPurchasePlan();
    }

    public String viewPurchasePlanDisplay() {

        currency = purchasePlan.getCurrency();
        urgent = purchasePlan.getUrgent();

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("purchasePlan", purchasePlan);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("currency", currency);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("urgent", urgent);

        return "viewPurchasePlanDisplay?faces-redirect=true";
    }

    public void viewPurchaseOrderDisplayPO(ActionEvent event) {
        rmpo = (RawMaterialPurchaseOrder) event.getComponent().getAttributes().get("selected");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("rmpo", rmpo);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("purchasePlan", purchasePlan);
    }

    public void displayBack(ActionEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("purchasePlan", purchasePlan);
    }

    //--------------------------------------------------------------------------
    //                               Getter and Setter
    //--------------------------------------------------------------------------
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public ArrayList<SupplierListRow> getSuppliersList() {
        return suppliersList;
    }

    public void setSuppliersList(ArrayList<SupplierListRow> suppliersList) {
        this.suppliersList = suppliersList;
    }

    public ArrayList<Long> getRequirements() {
        return requirements;
    }

    public void setRequirements(ArrayList<Long> requirements) {
        this.requirements = requirements;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public SupplierListRow getSr() {
        return sr;
    }

    public void setSr(SupplierListRow sr) {
        this.sr = sr;
    }

    public RawMaterialSupplyInformation getRmsi() {
        return rmsi;
    }

    public void setRmsi(RawMaterialSupplyInformation rmsi) {
        this.rmsi = rmsi;
    }

    public Long getQuantity() {
        return quantity;
    }

    public void setQuantity(Long quantity) {
        this.quantity = quantity;
    }

    public Boolean getCurrency() {
        return currency;
    }

    public void setCurrency(Boolean currency) {
        this.currency = currency;
    }

    public PurchasePlan getPurchasePlan() {
        return purchasePlan;
    }

    public void setPurchasePlan(PurchasePlan purchasePlan) {
        this.purchasePlan = purchasePlan;
    }

    public Boolean getUrgent() {
        return urgent;
    }

    public void setUrgent(Boolean urgent) {
        this.urgent = urgent;
    }

    public RawMaterialPurchaseOrder getRmpo() {
        return rmpo;
    }

    public void setRmpo(RawMaterialPurchaseOrder rmpo) {
        this.rmpo = rmpo;
    }

    public ArrayList<SupplierListRow> getSuppliersListBackup() {
        return suppliersListBackup;
    }

    public void setSuppliersListBackup(ArrayList<SupplierListRow> suppliersListBackup) {
        this.suppliersListBackup = suppliersListBackup;
    }

    public String getStatusMsg() {
        return statusMsg;
    }

    public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
    }
}
